Unity实用功能之ScrollView 定位功能

您所在的位置:网站首页 unity ping Unity实用功能之ScrollView 定位功能

Unity实用功能之ScrollView 定位功能

2023-03-14 21:28| 来源: 网络整理| 查看: 265

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

概述

在我们使用untiy的UGUI的SCrollView时,经常会有这种问题,就是当整个ScrollView超长时,想要找到其中的某一个Item就非常的困难,往往需要翻找很长时间,非常的麻烦,今天就主要讲解一下,ScrollView的定位功能,根据Item的索引,直接让滑动条显示到对应Item的位置。

思路分析

想要进行定位滑动条,首先要知道,ScrollView是通过哪一个参数进行控制的,通过查看API,我们可以发现,他是通过VerticalNormalizedPosition和HorizontalNormalizedPosition控制其纵向和横向滑动的,所以我们而他们的范围在0-1之间,所我们需要通过item的位置,间接的计算出VerticalNormalizedPosition和HorizontalNormalizedPosition的值,从而才能控制ScrollView的定位

功能实现 场景搭建

1、创建一个ScrollView,在Content中创建多个Item(使Content的长度超出ScrollView的长度,要不然定位看不到效果)。接着在Content身上添加组VerticalLayoutGroup(自动排列组件,根据排列需求添加)和ContentSizeFitter(自动设置宽度)。最终界面如下:

image.png 2、添加对应Item个数的按钮,好点击定位用,这里使用到了GridLayoutGroup(也是自动拍列),更快的自动拍列,不需要一个个摆了

image.png

代码实现

接下来就来看一下代码部分,首先来排除几个无法定位的情况,然后我们再继续。

1、ScrollView下没有Content或Viewport,说明这个ScrollView有问题,是空的,那么这种情况我们就只能够退出了,没法计算

if (scrollRect.viewport == null || scrollRect.content == null) { Debug.LogError("ScrollView的Content或Viewport为空"); return inverse ? 1 : 0; } 复制代码

2、Content下面没有物体或不是RectTransform,这个首先判断ScrollView下是否有物体,其次,验证下ScrollView是否在canvas中,是否有效,没有,那也不行

var childTrans = scrollRect.content.GetChild(0) as RectTransform; if (childTrans == null) { Debug.LogError("Content下面没有物体或不是RectTransform"); return inverse ? 1 : 0; } 复制代码

3、vertical和horizontal只能勾选一个,两个同时勾选的计算有点问题,后期修改完可能会补充,目前只支持只勾选其中一项的计算,所以这里做了个退出处理

if (scrollRect.vertical && scrollRect.horizontal) { Debug.LogError("vertical和horizontal只能勾选一个"); return inverse ? 1 : 0; } 复制代码

4、获取VerticalLayoutGroup或HorizontalLayoutGroup失败,这个主要是我用到了这个拍列组合,需要使用里面的的参数,比如说间距等,如果没有用到就可以忽略此条

VerticalLayoutGroup group = scrollRect.content.GetComponent(); if (group == null) { Debug.LogError("获取VerticalLayoutGroup失败"); return inverse ? 1 : 0; } 复制代码 HorizontalLayoutGroup group = scrollRect.content.gameObject.GetComponent(); if (group == null) { Debug.LogError("获取HorizontalLayoutGroup失败"); return inverse ? 1 : 0; } 复制代码

5、接下来就是计算位置了,获取对应的值的问题了。 首先分是Vertical还是Horizontal,如果是Horizontal就使用rect.Width,如果是Vertical就使用rect.Hight。这里还有区分一个问题,那就是滑动条的反正问题,即从上而下、从右往左要反着来,需要考虑是都使用1-计算值。其次,要获取几个值 每个条目的宽或高,加上的值是组件设置的间隔,这个是要加上的

float elementLength = childrenRect.height + group.spacing; 复制代码

content.rect和viewport.rect的差值

var diff = contentRect.height - viewportRect.height; 复制代码

算完所有的值之后就是开始计算值了,其中pixelOffset是像素偏移,向下向右为正,可有可无,根据需求

if (inverse) return Mathf.Clamp01(1 - (currentChildIndex * elementLength + pixelOffset) / diff); else return Mathf.Clamp01((currentChildIndex * elementLength - pixelOffset) / diff); 复制代码 效果展示

大家还可以发挥想象,比如说对定位的Item添加高亮等,这个后期可能也会进行补充 0829.gif

源代码分享

这是项目工程文件 GitHub下载地址:点击这里跳转下载

写在最后

所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。欢迎大家相互学习进步。本片文章就先写到这里,希望对你能够有所帮助



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3